-- Lua Battle System - 测试辅助工具

-- 设置Lua路径
package.path = package.path .. ';src/?.lua;src/utils/?.lua;src/characters/?.lua;src/skills/?.lua;src/items/?.lua;src/ai/?.lua;src/battle/?.lua;res/data/?.lua'

local Logger = require("utils.logger")
local Character = require("characters.character")

local TestHelpers = {}

-- 测试数据工厂
TestHelpers.Factory = {}

-- 创建测试角色
function TestHelpers.Factory.create_character(options)
    options = options or {}

    local default_options = {
        id = "test_character_" .. tostring(math.random(1000, 9999)),
        name = "Test Character",
        level = 1,
        max_hp = 100,
        hp = 100,
        max_mp = 50,
        mp = 50,
        attack = 20,
        defense = 10,
        magic_attack = 15,
        magic_defense = 8,
        speed = 15,
        luck = 10,
        team_id = 1,
        position = 1
    }

    -- 合并默认选项和用户选项
    for key, value in pairs(options) do
        default_options[key] = value
    end

    return Character:new(default_options)
end

-- 创建战士角色
function TestHelpers.Factory.create_warrior(options)
    options = options or {}

    local warrior_options = {
        id = options.id or "warrior_" .. tostring(math.random(1000, 9999)),
        name = options.name or "Warrior",
        level = options.level or 1,
        max_hp = options.max_hp or 150,
        hp = options.hp or 150,
        max_mp = options.max_mp or 30,
        mp = options.mp or 30,
        attack = options.attack or 25,
        defense = options.defense or 15,
        magic_attack = options.magic_attack or 10,
        magic_defense = options.magic_defense or 12,
        speed = options.speed or 12,
        luck = options.luck or 8
    }

    return TestHelpers.Factory.create_character(warrior_options)
end

-- 创建法师角色
function TestHelpers.Factory.create_mage(options)
    options = options or {}

    local mage_options = {
        id = options.id or "mage_" .. tostring(math.random(1000, 9999)),
        name = options.name or "Mage",
        level = options.level or 1,
        max_hp = options.max_hp or 80,
        hp = options.hp or 80,
        max_mp = options.max_mp or 100,
        mp = options.mp or 100,
        attack = options.attack or 12,
        defense = options.defense or 8,
        magic_attack = options.magic_attack or 25,
        magic_defense = options.magic_defense or 15,
        speed = options.speed or 10,
        luck = options.luck or 12
    }

    return TestHelpers.Factory.create_character(mage_options)
end

-- 创建敌人角色
function TestHelpers.Factory.create_enemy(options)
    options = options or {}

    local enemy_options = {
        id = options.id or "enemy_" .. tostring(math.random(1000, 9999)),
        name = options.name or "Enemy",
        level = options.level or 1,
        max_hp = options.max_hp or 60,
        hp = options.hp or 60,
        max_mp = options.max_mp or 20,
        mp = options.mp or 20,
        attack = options.attack or 15,
        defense = options.defense or 5,
        magic_attack = options.magic_attack or 8,
        magic_defense = options.magic_defense or 3,
        speed = options.speed or 8,
        luck = options.luck or 5,
        team_id = options.team_id or 2,
        is_controlled = false
    }

    return TestHelpers.Factory.create_character(enemy_options)
end

-- 创建技能
function TestHelpers.Factory.create_skill(options)
    options = options or {}

    local default_skill = {
        id = options.id or "test_skill",
        name = options.name or "Test Skill",
        type = options.type or "attack",
        damage = options.damage or 20,
        cost = options.cost or { mp = 10 },
        range = options.range or 1,
        target_type = options.target_type or "single",
        effects = options.effects or {},
        cooldown = options.cooldown or 0
    }

    return default_skill
end

-- 创建物品
function TestHelpers.Factory.create_item(options)
    options = options or {}

    local default_item = {
        id = options.id or "test_item",
        name = options.name or "Test Item",
        type = options.type or "consumable",
        effect = options.effect or { heal = 50 },
        stack_size = options.stack_size or 10,
        value = options.value or 100
    }

    return default_item
end

-- 创建装备
function TestHelpers.Factory.create_equipment(options)
    options = options or {}

    local default_equipment = {
        id = options.id or "test_equipment",
        name = options.name or "Test Equipment",
        type = options.type or "weapon",
        slot = options.slot or "weapon",
        stats = options.stats or {
            attack_bonus = 10,
            defense_bonus = 5
        }
    }

    return default_equipment
end

-- 测试环境管理
TestHelpers.Environment = {}

-- 设置测试环境
function TestHelpers.Environment.setup()
    -- 初始化日志系统
    Logger.init({
        level = "error"  -- 减少测试时的日志输出
    })

    -- 可以在这里添加其他环境设置
    print("Test environment setup completed")
end

-- 清理测试环境
function TestHelpers.Environment.cleanup()
    -- 可以在这里添加清理逻辑
    print("Test environment cleanup completed")
end

-- 创建临时测试目录
function TestHelpers.Environment.create_temp_dir()
    local temp_dir = "/tmp/lua_battle_test_" .. tostring(os.time())
    os.execute("mkdir -p " .. temp_dir)
    return temp_dir
end

-- 删除临时测试目录
function TestHelpers.Environment.remove_temp_dir(dir_path)
    if dir_path and dir_path:find("/tmp/lua_battle_test_") == 1 then
        os.execute("rm -rf " .. dir_path)
    end
end

-- 测试数据验证
TestHelpers.Validation = {}

-- 验证角色数据
function TestHelpers.Validation.validate_character(character, expected)
    local errors = {}

    if expected.id and character.id ~= expected.id then
        table.insert(errors, string.format("Expected id %s, got %s", expected.id, character.id))
    end

    if expected.name and character.name ~= expected.name then
        table.insert(errors, string.format("Expected name %s, got %s", expected.name, character.name))
    end

    if expected.level and character.level ~= expected.level then
        table.insert(errors, string.format("Expected level %s, got %s", expected.level, character.level))
    end

    if expected.max_hp and character.max_hp ~= expected.max_hp then
        table.insert(errors, string.format("Expected max_hp %s, got %s", expected.max_hp, character.max_hp))
    end

    if expected.hp and character.hp ~= expected.hp then
        table.insert(errors, string.format("Expected hp %s, got %s", expected.hp, character.hp))
    end

    if expected.is_alive ~= nil and character.is_alive ~= expected.is_alive then
        table.insert(errors, string.format("Expected is_alive %s, got %s", tostring(expected.is_alive), tostring(character.is_alive)))
    end

    return #errors == 0, errors
end

-- 验证技能数据
function TestHelpers.Validation.validate_skill(skill, expected)
    local errors = {}

    if expected.id and skill.id ~= expected.id then
        table.insert(errors, string.format("Expected skill id %s, got %s", expected.id, skill.id))
    end

    if expected.name and skill.name ~= expected.name then
        table.insert(errors, string.format("Expected skill name %s, got %s", expected.name, skill.name))
    end

    if expected.type and skill.type ~= expected.type then
        table.insert(errors, string.format("Expected skill type %s, got %s", expected.type, skill.type))
    end

    return #errors == 0, errors
end

-- 性能测试工具
TestHelpers.Performance = {}

-- 测量函数执行时间
function TestHelpers.Performance.measure_time(func, iterations)
    iterations = iterations or 1

    local start_time = os.clock()

    for i = 1, iterations do
        func()
    end

    local end_time = os.clock()
    local total_time = end_time - start_time
    local avg_time = total_time / iterations

    return {
        total_time = total_time,
        average_time = avg_time,
        iterations = iterations
    }
end

-- 内存使用情况（简单版本）
function TestHelpers.Performance.get_memory_usage()
    -- 这是一个简化的内存使用检查，实际实现可能需要更复杂的方法
    collectgarbage("collect")
    return collectgarbage("count")
end

-- 测试断言辅助函数
TestHelpers.Assertions = {}

-- 断言函数抛出错误
function TestHelpers.Assertions.assert_error(func, expected_error_pattern)
    local success, error_msg = pcall(func)

    if success then
        return false, "Expected function to throw an error, but it didn't"
    end

    if expected_error_pattern and not string.find(tostring(error_msg), expected_error_pattern) then
        return false, string.format("Expected error message containing '%s', got '%s'", expected_error_pattern, tostring(error_msg))
    end

    return true, nil
end

-- 断言表包含指定键值对
function TestHelpers.Assertions.assert_table_contains(table, expected_key, expected_value)
    if type(table) ~= "table" then
        return false, "Expected table, got " .. type(table)
    end

    local actual_value = table[expected_key]

    if actual_value == nil then
        return false, string.format("Table does not contain key '%s'", expected_key)
    end

    if expected_value ~= nil and actual_value ~= expected_value then
        return false, string.format("Expected key '%s' to have value '%s', got '%s'", expected_key, tostring(expected_value), tostring(actual_value))
    end

    return true, nil
end

-- 随机测试数据生成器
TestHelpers.Random = {}

-- 生成随机字符串
function TestHelpers.Random.string(length)
    length = length or 10
    local chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
    local result = ""

    for i = 1, length do
        local index = math.random(1, #chars)
        result = result .. string.sub(chars, index, index)
    end

    return result
end

-- 生成随机数字
function TestHelpers.Random.number(min, max)
    min = min or 1
    max = max or 100
    return math.random(min, max)
end

-- 生成随机角色
function TestHelpers.Random.character()
    return TestHelpers.Factory.create_character({
        id = "random_char_" .. TestHelpers.Random.string(8),
        name = "Random Character " .. TestHelpers.Random.string(5),
        level = TestHelpers.Random.number(1, 10),
        max_hp = TestHelpers.Random.number(50, 200),
        attack = TestHelpers.Random.number(10, 30),
        defense = TestHelpers.Random.number(5, 20)
    })
end

return TestHelpers